home *** CD-ROM | disk | FTP | other *** search
- From jdc@naucse.cse.nau.edu Thu Mar 5 09:26:56 1992
- Return-Path: <jdc@naucse.cse.nau.edu>
- Received: from naucse.cse.nau.edu by ra-next.arc.nasa.gov (NeXT-1.0 (From Sendmail 5.52)/NeXT-1.0)
- id AA10629; Thu, 5 Mar 92 09:26:37 PST
- Received: by naucse.cse.nau.edu (5.65c/1.5-nau)
- id AA21527; Thu, 5 Mar 1992 10:32:21 -0700
- Message-Id: <199203051732.AA21527@naucse.cse.nau.edu>
- From: jdc@naucse.cse.nau.edu (John Campbell)
- Date: Thu, 5 Mar 1992 10:32:20 MST
- X-Mailer: Mail User's Shell (7.2.3 5/22/91)
- To: woo@ra-next.arc.nasa.gov
- Subject: gplotlib.shr2
- Status: R
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 5)."
- # Contents: bar.c cpr.1 cpr.c intro.doc
- # Wrapped by jdc@naucse.cse.nau.edu on Tue Feb 11 08:42:13 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'bar.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bar.c'\"
- else
- echo shar: Extracting \"'bar.c'\" \(7149 characters\)
- sed "s/^X//" >'bar.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include "gsr.h"
- X
- X#define DEBUG
- X#undef DEBUG
- X
- Xchar *ylabel="", *xlabel="", *title="", *term=NULL;
- X
- X/* externs needed for getopt */
- Xextern char *optarg;
- Xextern int optind, opterr; /* 0 opterr: print err message and return "?" */
- X
- X/*
- X Do bar plots:
- X bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]
- X*/
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *in, *fopen();
- X int c;
- X
- X/* Check options. */
- X while ((c = getopt (argc, argv, "x:y:t:T:")) != EOF) {
- X switch (c) {
- X case 'x':
- X xlabel = optarg;
- X break;
- X case 'y':
- X ylabel = optarg;
- X break;
- X case 't':
- X title = optarg;
- X break;
- X case 'T':
- X term = optarg;
- X break;
- X case '?':
- X default:
- X usage();
- X }
- X }
- X/* Find out what terminal we're on to compute the max number of points. */
- X gt_init_terminal();
- X if (term != NULL)
- X gt_change_term (term, -1);
- X if (GTterm == 0) {
- X fprintf (stderr, "Unknown terminal\n");
- X exit(1);
- X }
- X
- X if (argc <= optind) {
- X bar_graph(stdin);
- X if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
- X getchar();
- X }
- X else {
- X for (; optind < argc; ++optind) {
- X if ((in = fopen (argv[optind], "r")) == NULL) {
- X fprintf (stderr, "Can't open %s\n", argv[optind]);
- X usage();
- X }
- X bar_graph(in);
- X if (isatty(fileno(stdout)) && isatty(fileno(stdin)))
- X getchar();
- X }
- X }
- X gsr_reset_terminal();
- X}
- X
- X
- Xbar_graph(in)
- XFILE *in;
- X/*
- X Routine to make a bar graph out of a list of points. The list of
- X points come from the file named on the command line.
- X
- X Parameter:
- X
- X in: Pointer to file descriptor containing list of points.
- X*/
- X{
- X#define MAXBUF 255
- X struct termentry *t = >term_tbl[GTterm];
- X int *pnum, bar_w, x_loc, height, lcnt, max_points;
- X int err, i, k, result, bar_cnt=0;
- X float *pval, scale, pmax, pmin, dummy;
- X char buf[MAXBUF];
- X
- X max_points = (t->xmax - 4*t->h_char)/2;
- X
- X/* Read everything into an array of floats with room for 10 per line. */
- X pval = (float *)malloc (10*sizeof(float)*max_points);
- X pnum = (int *)malloc (sizeof(int )*max_points);
- X pmin = VERYLARGE;
- X pmax = -VERYLARGE;
- X err = 0;
- X for (lcnt=0; fgets (buf, MAXBUF, in) != NULL; ++lcnt) {
- X result = sscanf(buf,"%f %f %f %f %f %f %f %f %f %f %f",
- X &pval[lcnt*10], &pval[lcnt*10+1], &pval[lcnt*10+2], &pval[lcnt*10+3],
- X &pval[lcnt*10+4], &pval[lcnt*10+5], &pval[lcnt*10+6], &pval[lcnt*10+7],
- X &pval[lcnt*10+8], &pval[lcnt*10+9], &dummy);
- X if (result > 10) {
- X err = 1;
- X break;
- X }
- X /* Find the max and min of the overall array. */
- X for (k = 0; k < result; ++k) {
- X if (pval[lcnt*10+k] > pmax) pmax = pval[lcnt*10+k];
- X if (pval[lcnt*10+k] < pmin) pmin = pval[lcnt*10+k];
- X }
- X pnum[lcnt] = result; /* number of items on this line. */
- X bar_cnt += result;
- X if (bar_cnt > max_points) {
- X err = 1;
- X break;
- X }
- X }
- X if (bar_cnt >= max_points) {
- X fprintf (stderr, "Error on input: more than %d data elements\n", bar_cnt);
- X exit(1);
- X }
- X if (err) {
- X fprintf (stderr, "Error on input: line %d\n", lcnt);
- X exit(1);
- X }
- X
- X/* Now that we know max and min, we can initialize the plotting device. */
- X gsr_init (stdout, 1.0, 100.0, pmin < 0.0 ? pmin : 0.0, pmax, 1, 1, 0, 0);
- X
- X/* Draw the bars represented by the array pval. */
- X bar_plot (pval, pnum, lcnt, pmax, pmin);
- X}
- X
- X
- Xusage()
- X{
- X fprintf (stderr,
- X"usage: bar [-x xlabel] [-y ylabel] [-t title] [-T term] [file [file2 ...]]\n");
- X fprintf (stderr, "List of terminals (on standard output):\n");
- X gt_list_terms();
- X exit(1);
- X}
- X
- X
- Xbar_plot (pval, pnum, lcnt, pmax, pmin)
- Xfloat pval[], pmax, pmin;
- Xint pnum[], lcnt;
- X/*
- X Routine to draw the bars represented by values in array pval.
- X
- X Parameters:
- X
- X pval: array of groups of points to take as bar heights.
- X
- X pnum: array of the number of points in the ith bar group.
- X
- X lcnt: number of groups (10 at most per group) of bars to draw.
- X
- X pcnt: number of points to draw.
- X
- X pmax: largest value in the pval array.
- X
- X pmin: smallest value in the pval array.
- X*/
- X{
- X int i, j, k, bar_cnt, zero, bar_h, bar_w, x_loc;
- X struct termentry *t = >term_tbl[GTterm];
- X
- X/* Compute the width of the bar graph. */
- X for (bar_cnt=i=0; i < lcnt; ++i)
- X bar_cnt += pnum[i]+1;
- X
- X bar_w = (GSRxright - GSRxleft)/bar_cnt;
- X
- X/* Compute start of first bar. */
- X x_loc = (GSRxright - (bar_cnt-1)*bar_w)/2.0 + GSRxleft/2.0 + 0.5;
- X
- X zero = gsr_map_y (0.0);
- X
- X#ifdef DEBUG
- X for (i=0; i < lcnt; ++i) {
- X fprintf (stderr, "%d: pval[%d] = ", pnum[i], i*10);
- X for (k=0; k < pnum[i]; ++k) {
- X fprintf (stderr, "%f ", pval[i*10+k]);
- X }
- X fprintf (stderr,"\n");
- X }
- X fprintf (stderr, "lcnt = %d\t", lcnt);
- X fprintf (stderr, "pmax = %f\t", pmax);
- X fprintf (stderr, "pmin = %f\n", pmin);
- X fprintf (stderr, "zero = %d\t", zero);
- X fprintf (stderr, "bar_cnt = %d\n", bar_cnt);
- X fprintf (stderr, "bar_w = %d\n", bar_w);
- X fprintf (stderr, "Hit return\n");
- X (void )getchar();
- X#endif
- X
- X/* Put device into graphics mode. */
- X gsr_graphics();
- X
- X/* Draw a box around the plot. */
- X gsr_boundary();
- X
- X/* Draw tics for the y axis of the plot. */
- X gsr_draw_tics (0, 0, 0, 1, 1, 1);
- X
- X/* Write the ylabel, xlabel, and title to the plot. */
- X gsr_ylabel (ylabel);
- X gsr_xlabel (xlabel);
- X gsr_title (title);
- X
- X/* Draw the zero line (we might want a different line type here). */
- X if (pmin < 0.0)
- X gsr_draw_axis (0.0, 0.0, 2); /* Just y axis */
- X
- X/* Put the linetype back to something we expect. */
- X gsr_line_point_type (0, 0);
- X
- X/* Draw lcnt bars of height pval[i] and width bar_w. */
- X for (i = 0; i < lcnt; ++i) {
- X for (k = 0; k < pnum[i]; ++k) {
- X bar_h = gsr_map_y (pval[i*10+k]);
- X
- X#ifdef DEBUG
- X fprintf (stderr, "bar_h = %d, linetype = %d\n", bar_h, k);
- X#endif
- X
- X /* Draw the bar's rectangle. */
- X (*t->move)(x_loc,zero);
- X (*t->vector)(x_loc, bar_h);
- X (*t->vector)(x_loc+bar_w, bar_h);
- X (*t->vector)(x_loc+bar_w, zero);
- X
- X /* Shade in the rectangle just drawn. */
- X if (k % 6 < 4) {
- X for (j=0; j < bar_w; ++j) {
- X /* Terminal drivers define points as unsigned int... */
- X (*t->move)(x_loc+j,zero);
- X if (j % (k % 4 + 1) == 0)
- X (*t->vector)(x_loc+j,bar_h);
- X }
- X }
- X else {
- X int lower, upper;
- X if (zero < bar_h) {
- X lower = zero;
- X upper = bar_h;
- X }
- X else {
- X lower = bar_h;
- X upper = zero;
- X }
- X for (j=lower; j < upper; ++j) {
- X if (j % (k % 3 + 1) == 0) {
- X (*t->move)(x_loc,j);
- X (*t->vector)(x_loc+bar_w,j);
- X }
- X }
- X }
- X x_loc += bar_w;
- X }
- X x_loc += bar_w;
- X }
- X/* Back into text mode (to see the plot generated) */
- X gsr_text();
- X}
- X
- X
- X
- END_OF_FILE
- if test 7149 -ne `wc -c <'bar.c'`; then
- echo shar: \"'bar.c'\" unpacked with wrong size!
- fi
- # end of 'bar.c'
- fi
- if test -f 'cpr.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cpr.1'\"
- else
- echo shar: Extracting \"'cpr.1'\" \(7847 characters\)
- sed "s/^X//" >'cpr.1' <<'END_OF_FILE'
- X.\" to produce the man page.
- X.\" troff -man -Tdumb cpr.tf | ddumb >cpr.p
- X.\"
- X.TH CPR 1L "14 Feb 1990"
- X.SH "NAME"
- Xcpr \- Code print (prepare source code for printing)
- X.SH "SYNOPSIS"
- X.B cpr
- X[\fB-CcFhiNnOsS\fR] [\fB-a\fI language\fR] [\fB-H\fI header\fR]
- X[\fB-l\fI pagelen\fR] [\fB-o\fI offset\fR] [\fB-P\fI printer\fR]
- X[\fB-p\fR[\fInum\fR]] [\fB-r\fR[\fInum\fR]] [\fB-T\fI title\fR]
- X[\fB-t\fI tabwidth\fR] [[\fB-f\fI flist\fR] | \fBfile...\fR]
- X.SH "DESCRIPTION"
- X.I cpr
- Xprints the files named in its argument list, preceding
- Xthe output with a table of contents. (If there are not enough pages of
- Xoutput or enough table of content entries then printing the table of contents
- Xis normally suppressed).
- XIf a filename is preceded by
- X.B -f
- Xthen the specified file is assumed to contain a list of files to be
- Xprinted. The filename "-" specifies standard input.
- XEach file printed is assumed to be source code in a "known" language
- Xand \fIcpr\fR searches
- Xfor the beginning and end of functions.
- XFunction names are added to
- Xthe table of contents and each function name in the output is bolded
- X(unless a printer type of DUMB is assumed).
- X.PP
- XNormally the suffix (.c, .y, .for, .f, .icn, .lsp, .l) of the file name
- Xdetermines which language is chosen
- Xin order to identify the beginning and end of
- Xfunctions. This can be overridden with the -a option described below.
- XNote that Lisp programs are expected to end in .lsp or .l, but lex
- Xprograms also end in .l. In this case, \fIcpr\fR reads a few lines of code
- Xlooking for % lex constructs or '(' lisp constructs to make its determination.
- XIf, when running in AUTO mode, \fIcpr\fR can't determine the language of the
- Xsource code it will issue a warning to stderr and process the file with
- Xlanguage set to NONE.
- X.PP
- XBy default, blank lines are inserted at the end of every function (or
- Xsubroutine).
- XThus functions and structure declarations are nicely
- Xisolated in the output. Occasionally, however, structure
- Xinitialization tables may produce lots of white space.
- XThe \fB\-r\fP[\fInum\fR] option changes the space left to the specified
- Xnumber of lines. If 0 is specified, no space is left.
- X.PP
- XOriginally \fIcpr\fR assumed the printer could backspace--and
- Xdid bolding by using backspaces. Most laser printers, and some
- Xbrain dead line printers, however, can not bold by backspacing. Support for
- Xother printers was added using the environment variable CPRINTER. Defining
- Xthe environment variable CPRINTER as DUMB, BACKSPACE, ANSI, LN03,
- XNECP5200, or POSTSCRIPT
- Xselects an appropriate printer initialization and bolding
- Xstyle. ("DUMB" does no initialization or bolding, "BACKSPACE" uses ^H
- Xcharacters to achieve bolding, and POSTSCRIPT generates a file that can
- Xbe printed on a postscript printer.)
- X.SH "Options"
- X.TP
- X\fB\-C\fP\ \ requests \fIcpr\fR to ignore the heuristic that tests whether
- Xa table of contents is worth printing. Normally \fIcpr\fR won't print
- Xtables of contents that are too small (too few routine
- Xnames) or reference too few pages. \fB-C\fP overrides this heuristic and
- Xcauses the table to always be printed.
- X.TP
- X\fB\-c\fP\ \ requests \fIcpr\fR to produce only a table of contents, the
- Xfile contents themselves are not printed (-c implies -C and overrides -F).
- X.TP
- X\fB\-F\fP\ \ requests \fIcpr\fR to produce only a listing of files, the
- Xtable of contents is not printed.
- X.TP
- X\fB\-h\fP\ \ produces a help message giving options and command syntax.
- X.TP
- X\fB\-i\fP\ \ forces \fBcpr\fP to ignore form-feeds in the original source.
- XBy default form-feeds found at the start of a line and terminated by the
- Xend of a line are treated as page breaks and inserted at the point they are
- Xencountered.
- X.TP
- X\fB\-N\fP\ \ forces page numbering to start with page 1 for each
- Xfile processed.
- X.TP
- X\fB\-n\fP\ \ indicates that output lines should be numbered with
- Xthe corresponding line number from the input file.
- X.TP
- X\fB\-O\fP\ \ assumes output is destined for a 2-up printer. In this case
- Xeach file is started on an odd-numbered physical page and -T, and table
- Xof contents entries are accounted for when producing the output.
- X.TP
- X\fB\-s\fP\ \ indicates that the table of contents should be sorted
- Xby function name within each file. By default the sort is case
- Xsensitive.
- X.TP
- X\fB\-S\fP\ \ do the sort just mentioned in a case-insensitive
- Xmanner. (\fB\-S\fP implies \fB\-sS\fP).
- X.TP
- X\fB\-a\fI lang\fR
- XSelect the language to use. Default is AUTO, which
- Ximplies looking at the suffix (.y, .c, .f, .for, .l, .lsp) to determine
- Xwhich language is in use. If no language is desired (no function names
- Xare highlighted) then \fB\-a NONE\fR may be used. The current choices
- Xare \fIC\fR, \fIFORTRAN\fR, \fIICON\fR, and \fILISP\fR.
- XChoosing a language will apply that choice to all files regardless
- Xof the file suffix.
- X.TP
- X\fB\-H\fI header\fR
- XUse this \fIheader\fR instead of the
- Xfile name on the header line.
- X.TP
- X\fB\-l\fI pagelen\fP
- XUse this \fIpagelen\fR as the page length, rather
- Xthan the default 66 lines.
- X.TP
- X\fB\-o\fI offset\fP
- XInsert \fIoffset\fR number of blanks in front of
- Xeach line of source code.
- X.TP
- X\fB-P\fI\ printer\fR
- XOverride the default printer and the environment variable CPRINTER.
- XThe value of \fIprinter\fR can be any of the printers CPRINTER
- Xsupports (see above). Adding a new
- Xprinter to the source code is not very hard and may be worth doing if
- Xthere is a special font or bolding method that would work better.
- X.TP
- X\fB-p\fR[\fInum\fR]
- XIndicate what proportion of the page in steps of 16
- Xshould be used for deciding if a new function needs a new page.
- XThat is \fB-p12\fR (the default) indicates that if a function starts
- Xwithin the top 12/16 (3/4) of the page then do it, otherwise put it
- Xon a new page.
- XThus the higher the number (up to 16) the closer to
- Xthe bottom of the page will functions be started.
- X.B -p0
- Xsays put each function on a new page, and is the default if no \fInum\fP
- Xis specified.
- X.TP
- X\fB-r\fR[\fInum\fR]
- XSpecify the number of blank lines to insert between
- Xfunctions (put out after seeing the function end). \fB\-r0\fR leaves the
- Xoutput as it was in the original source code. The default is 5 blank
- Xlines between functions.
- X.TP
- X\fB\-T\fI title\fP
- XCause \fIcpr\fR to print the contents of the file
- X\fItitle\fR before printing the table of contents.
- X.TP
- X\fB\-t\fI\ tabwidth\fR
- XCause output to be produced that will look correct with tabs expanded every
- X\fItabwidth\fR columns. (The default is every 8 columns.)
- XAll output is processed with tabs expanded to spaces.
- X.TP
- X\fB\-f\fI flist\fR
- XObtain the list of files to print from the file \fIflist\fP rather
- Xthan from the command line.
- X.SH "FILES"
- X.nf
- X/tmp/cpr$$ \- temp files holding text
- X.fi
- X.SH "SEE ALSO"
- Xcb(1), cat(1), fold(1), num(1), pr(1), tgrind(l), vgrind(l)
- X.SH "DIAGNOSTICS"
- XVarious messages about being unable to open files or not finding the
- Xlanguage.
- XSelf explanatory.
- X.SH "BUGS"
- X\fICpr\fR may sometimes make a mistake in determining the language
- Xor identifying functions. In 'C',
- Xfunctions declarations whose opening ( is not found on the same line
- Xas the function name will not be recognized. Some forms of macros
- Xalso confuse the function recognition. Also,
- X#ifdef's are not processed,
- Xso stuff inside them gets interpreted, which is especially annoying
- Xif the code has mismatched braces in these blocks.
- X.SH "AUTHOR(S)"
- X.IP "Paul Breslin" 2.0i
- Xoriginal, Human Computing Resources Corp.
- X.IP "Rick Wise" 2.0i
- Xsorting and use of standard input, CALCULON Corp.
- X.IP "David Wasley" 2.0i
- Xnumbering, times, etc., U. C. Berkeley.
- X.IP "Patrick Powell" 2.0i
- Xvariable number of lines between functions, University of Waterloo
- X.IP "Ian! D. Allen" 2.0i
- Xvariable tabs; redundant TOC suppression, University of Waterloo
- X.IP "Dennis Vadura" 2.0i
- Xmore options; better function recognition,
- XUniversity of Waterloo
- X.IP "John Campbell" 2.0i
- Xheader, offset, and support for various languages.
- END_OF_FILE
- if test 7847 -ne `wc -c <'cpr.1'`; then
- echo shar: \"'cpr.1'\" unpacked with wrong size!
- fi
- # end of 'cpr.1'
- fi
- if test -f 'cpr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cpr.c'\"
- else
- echo shar: Extracting \"'cpr.c'\" \(27280 characters\)
- sed "s/^X//" >'cpr.c' <<'END_OF_FILE'
- X/* if UNIX: cc -O cpr.c
- X * if MSDOS: cc -O -DMSDOS cpr.c
- X * if VMS: define sys sys$library; cc cpr.c
- X *
- X * This program prints the files named in its argument list, preceding
- X * the output with a table of contents. Each file is assumed to be C
- X * source code (but doesn't have to be) in that the program searches
- X * for the beginning and end of functions. Function names are added to
- X * the table of contents, provided the name starts at the beginning of
- X * a line. The function name in the output is bolded.
- X *
- X * By default blank space is inserted after every closing '}'
- X * character. Thus functions and structure declarations are nicely
- X * isolated in the output. The only drawback to this is that structure
- X * initialization tables sometimes produce lots of white space.
- X * The "-r" option removes this space, or changes it to the indicated
- X * length.
- X *
- X * The option "-l" indicates that the following argument is to be
- X * the page length used for output (changing the page length hasn't been
- X * tested much).
- X *
- X * The option "-s" indicates that the table of contents should be sorted
- X * by function name within each file.
- X *
- X * The option "-n" indicates that output lines should be numbered with
- X * the corresponding line number from the input file.
- X *
- X * The option "-p" indicates what proportion of the page in steps of 16
- X * should be used for deciding if a new function needs a new page.
- X * That is -p12 (the default) indicates that if a function starts
- X * within the top 12/16 (3/4) of the page then do it, otherwise put it
- X * on a new page. Thus the higher the number (upto 16) the closer to
- X * the bottom of the page will functions be started. -p0 says put each
- X * func on a new page.
- X *
- X * Try it! You'll like it. (I call it cpr.c)
- X *
- X * Written by:
- X * Paul Breslin
- X * Human Computing Resources Corp.
- X * 10 St. Mary St.
- X * Toronto, Ontario
- X * Canada, M4Y 1P9
- X *
- X * -- ...!decvax!utcsrgv!hcr!phb
- X *
- X * Sorting and standard input reading from:
- X * Rick Wise, CALCULON Corp., Rockville, MD.
- X * -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
- X *
- X * File modified time,
- X * numbered output,
- X * optional white space,
- X * improved function start tests from:
- X * David Wasley, U.C.Berkeley
- X * -- ...!ucbvax!topaz.dlw
- X * Modified the -r to leave variable amounts of space
- X * Patrick Powell, U. Waterloo
- X *
- X * Changed handling of form feeds to start a new page AND print heading:
- X * Terry Doner, U of Waterloo
- X *
- X * Fixed up to locate more functions, and added -p option
- X * Dennis Vadura, U of Waterloo
- X * dvadura@watdragon.waterloo.edu (Dennis Vadura)
- X *
- X * It will find things like struct foo *f()...
- X * but not things like int
- X * f
- X * ()...
- X * ie. the constraint is that the () must appear on the same line
- X * as the function name.
- X *
- X * Clean up a bit for 80286 machines (lints a bit cleaner, too)
- X * Dan Frank, Prairie Computing
- X *
- X * Fixed a whole bunch of stuff and added lots of new flags.
- X * -S sort and be case insensitive.
- X * -N start numbering pages at 1 for each new file
- X * -T title cat the file title before the table of contents.
- X * -C print only the table of contents
- X * -c only try to look for function names in files whose suffix ends
- X * in .c
- X * -f file to handle file containing list of files to print. (for MSDOS)
- X * Dennis Vadura
- X *
- X * Added VMS and Language support, -h, -o options, reorganized bolding, and
- X * shortened long names (so page numbers aren't lost). Also put in getopt().
- X * Oh yeah, expanded tabs (which wasn't what -t originally meant).
- X * -h str String to put at the top of each page instead of file name.
- X * -o off Number of spaces to put in front of each line of code.
- X * -a lang Assume the following language. Default is AUTO (use file
- X * name suffix to guess language). NONE is allowed to mean
- X * don't look for function names at all.
- X * -cC Dennis Vadura's -c option is thus generalized and removed.
- X * -C becomes -c (VMS requires quotes around uppercase options,
- X * so where possible use lower case...) New -C added to override
- X * supression of table of contents for small output jobs. (NONE
- X * means no table of content entries, hence none printed.)
- X *
- X * Adding a language involves (at least):
- X * 1) Add to enum langs.
- X * 2) Add recognition of language keyword (FORTRAN) to getopt().
- X * 3) Add reference in man page and in Usage() function.
- X * 4) Add recognition to Scan() for end of functions.
- X * 5) Build a LooksLikeXXXX() to call inside LooksLikeFunction().
- X * 6) Add suffix recognition to WhichLanguage().
- X * Then search everywhere for Language and see if you've missed
- X * anything; if so edit this comment (smile).
- X *
- X * John Campbell (...!arizona!naucse!jdc or CAMPBELL@NAUVAX)
- X *
- X * Dennis Vadura:
- X * Added a few options, -i, to ignore form-feed chars in original
- X * source, -O to force output for two-up printing (this option
- X * affects both table of contents and the file listing output and
- X * handles the -T option correctly), added -F to print only file
- X * listings.
- X *
- X * renamed John Campbell's -h str to -H str so that -h can be used as
- X * help (ie. the -? gets you in trouble in most shells and you have to
- X * escape it etc.)
- X *
- X * Cleaned up printing of help message.
- X *
- X * Oh, what the hell, took the a2ps.c postscript converter and added the
- X * capability to produce a postscript output file. Seems Really nice,
- X * might need a bit of tweeking but hey, I don't have hours to spend.
- X * It's good enough for me :-)
- X *
- X * To do this I hacked the code quite a bit, re-organized some functions
- X * put in new ones, and made all output go through a common set of
- X * routines. I also changed cpr's output format to match that of the
- X * postscript code.
- X *
- X * I took the a2ps postscript code and embeded it into cpr, I prefered
- X * this over keeping it as an included separate file, in an effort to
- X * keep cpr self contained.
- X *
- X * Bumped the version # to 2.5.
- X */
- Xchar *version = "2.5"; /* Just a guess--never had one before. */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include <string.h>
- X#ifdef __TURBOC__
- X#define MSDOS 1
- X#endif
- X#ifndef VMS
- Xextern int errno; /* system error number */
- Xextern char *sys_errlist[]; /* error message */
- X#define CANT_OPEN(p1) \
- X fprintf(stderr,"%s: Can't open file '%s': %s\n", \
- X ProgName, p1, sys_errlist[errno] )
- X#else
- X#include <perror.h>
- X#define CANT_OPEN(p1) \
- X if (errno == EVMSERR) {\
- X fprintf (stderr, "Can't open %s\n", p1);\
- X LIB$STOP (vaxc$errno);\
- X }\
- X fprintf(stderr,"%s: Can't open file '%s': %s\n",\
- X ProgName, p1, sys_errlist[errno] )
- X#endif
- X#if MSDOS || VMS
- X#include "getopt.c"
- X#endif
- X
- Xextern char *malloc() ; /* important for 8086-like systems */
- X
- X#define FALSE 0
- X#define TRUE 1
- X
- X#define TOC_SIZE 4096
- X#define MAXLINE 256
- X
- X#define NEWFILE 1
- X#define NEWFUNCTION 2
- X
- X#define SMALLC 8 /* Too few contents for a table of contents. */
- X#define SMALLP 10 /* Too few pages for a table of contents. */
- X
- XFILE *File, *FList = NULL;
- X
- Xint Braces; /* Keeps track of brace depth */
- Xint LineNumber; /* Count output lines */
- Xint PageNumber = 1; /* You figure this one out */
- Xint ActualPageCount = 0; /* Actual number of pages printed */
- Xint PageLength = 66; /* -l <len> Normal paper length */
- Xint PagePart = 12; /* Decision on paging for new fn*/
- Xint PageEnd; /* Accounts for space at bottom */
- Xint SawFunction;
- Xint InComment;
- Xint InString;
- Xint ResetPage=0;
- Xint ContentsOnly=0;
- Xint FilesOnly=0;
- Xint AlwaysContents=0;
- Xint CaseInsensitive=0;
- Xint StartOdd=0;
- Xint IgnoreFF=0;
- X
- Xlong FileLineNumber; /* Input file line number */
- X
- Xchar *TitleFile = NULL;
- Xchar *ProgName;
- Xchar Today[30];
- Xchar *Name; /* Current file name */
- Xchar *Header = NULL; /* User's header (-h "header") */
- Xchar *Title = NULL;
- X
- Xchar *FileDate; /* Last modified time of file */
- Xchar FunctionName[MAXLINE+1];
- X
- Xchar SortFlag; /* -s == sort table of contents */
- Xchar NumberFlag; /* -n == output line numbers */
- Xint OffsetValue = 0; /* -o <number> Offset each line (of code) N spaces */
- Xint Space_to_leave = 5; /* -r<number> space to leave */
- Xint TabWidth = 8; /* -t <number> width of tabs */
- X
- X/* Language types */
- Xenum langs {NONE, AUTO, C, FORTRAN, ICON, LISP}
- X Language = AUTO;
- X/*
- X Printer types (Would you believe I have to support a printer that can't
- X backspace? Geesh!)
- X*/
- X#define DUMB 0
- X#define BACKSPACE 1 /* Probably most reasonable default. */
- X#define ANSI 2 /* Just uses ansi escape sequences to bold */
- X#define LN03 3 /* For now same as ANSI--later smaller print! */
- X#define NECP5200 4 /* NEC 24 pin printer--in HS mode. */
- X#define POSTSCRIPT 5 /* print on a postscript printer */
- Xint Printer = BACKSPACE; /* Choose your default. */
- X
- Xextern char *optarg;
- Xextern int optind, opterr;
- X
- Xstatic char *Toc[TOC_SIZE];
- Xstatic int TocPages[TOC_SIZE];
- Xstatic int TocCount;
- X
- X
- X#ifdef VMS
- X#include <errno.h> /* Watch out for EVMSERR (special 65535 errno) */
- X#define unlink delete
- X#define toupper _toupper /* Faster to use macro version. */
- X/*
- X Local (NAU) support for redirection, other VMS sites can leave this out,
- X but then they can't use wild cards (*.c), or redirection (>cpr.out).
- X If you are a VMS site and want this contact CAMPBELL@NAUVAX.bitnet.
- X*/
- X#include "nau_utils:redexp.vms"
- X#endif
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X register int i;
- X char *ctime();
- X char *pname=NULL;
- X char *s;
- X time_t thetime, time();
- X int c;
- X enum langs start_lang, WhichLanguage();
- X
- X FileDate = (char *)malloc(100);
- X ProgName = argv[0];
- X thetime = time((time_t *)0);
- X strcpy(Today,ctime(&thetime));
- X if( (s = strchr(Today,'\n')) != NULL ) *s = '\0';
- X
- X/* Parse options. */
- X while ((c = getopt (argc, argv, "cCFhisSnNOa:f:H:t:T:l:o:r:p:P:")) != EOF) {
- X switch (c) {
- X case 'a': /* Assume a language ('C', FORTRAN,...) */
- X c = *optarg;
- X switch (c) {
- X case 'C':
- X case 'c':
- X Language = C;
- X break;
- X case 'F':
- X case 'f':
- X Language = FORTRAN;
- X break;
- X case 'I':
- X case 'i':
- X Language = ICON;
- X break;
- X case 'L':
- X case 'l':
- X Language = LISP;
- X break;
- X case 'N':
- X case 'n':
- X Language = NONE;
- X break;
- X case 'A':
- X case 'a':
- X Language = AUTO;
- X break;
- X default:
- X fprintf (stderr, "Unknown or unsupported language\n");
- X exit(1);
- X }
- X break;
- X
- X case 'F':
- X ++FilesOnly;
- X break;
- X
- X case 'O':
- X ++StartOdd;
- X break;
- X
- X case 'i':
- X ++IgnoreFF;
- X break;
- X
- X case 'f':
- X if (*optarg == '-') {
- X FList = stdin;
- X }
- X else if ((FList = fopen (optarg, "r")) == NULL) {
- X fprintf (stderr, "Can't open file names list %s\n", optarg);
- X exit(1);
- X }
- X break;
- X case 'H': /* User's header */
- X Header = optarg;
- X break;
- X
- X case 't':
- X TabWidth = atoi(optarg);
- X if( TabWidth < 0 )
- X TabWidth = 0;
- X break;
- X
- X case 'T':
- X TitleFile = optarg;
- X break;
- X
- X case 'l':
- X PageLength = atoi(optarg);
- X if( PageLength < 10) PageLength = 10;
- X break;
- X
- X case 'S':
- X ++CaseInsensitive;
- X case 's':
- X ++SortFlag;
- X break;
- X
- X case 'C':
- X ++AlwaysContents;
- X break;
- X
- X case 'c':
- X ++ContentsOnly;
- X break;
- X
- X case 'n':
- X ++NumberFlag;
- X break;
- X
- X case 'N':
- X ++ResetPage;
- X break;
- X
- X case 'o': /* Offset code by <number> */
- X OffsetValue = atoi(optarg);
- X if (OffsetValue <= 0) {
- X fprintf (stderr, "Offset must be a positive integer only\n");
- X exit(1);
- X }
- X if (OffsetValue > 32) {
- X fprintf (stderr, "Offset must be less than 32\n");
- X exit(1);
- X }
- X break;
- X
- X case 'r':
- X /* It's ok to have a '0' from the "?" here... */
- X Space_to_leave = atoi(optarg);
- X break;
- X
- X case 'P':
- X pname = optarg; /* Override printer default or CPRINTER environ */
- X break;
- X
- X case 'p':
- X PagePart = atoi(optarg);
- X PagePart = PagePart <= 16 ? PagePart : 16;
- X break;
- X
- X case 'h':
- X default:
- X Usage();
- X break;
- X }
- X }
- X
- X start_lang = Language;
- X
- X Init (pname);
- X StartTempFile();
- X
- X i = optind;
- X
- X if( FList == NULL && i == argc )
- X { /* no file names */
- X File = stdin;
- X Name = "Standard Input";
- X if (start_lang == AUTO) Language = C;
- X List();
- X }
- X
- X if( FList != NULL)
- X {
- X char b[1024];
- X
- X while( fgets(b, 1024, FList) != NULL )
- X {
- X if( strlen(b) ) b[strlen(b)-1]=0;
- X
- X if( strcmp(b, "-") != 0 )
- X {
- X if( (File = fopen( Name = b, "r" )) == NULL )
- X {
- X CANT_OPEN (Name);
- X continue;
- X }
- X if (start_lang == AUTO) {
- X Language = WhichLanguage (Name);
- X }
- X }
- X else {
- X Name = "Standard Input";
- X if (start_lang == AUTO) Language = C;
- X File = stdin;
- X }
- X
- X List();
- X if( File != stdin ) fclose(File);
- X }
- X }
- X for(; i < argc; ++i )
- X {
- X if( strcmp(argv[i], "-") == 0 )
- X {
- X File = stdin;
- X Name = "Standard Input";
- X if (start_lang == AUTO) Language = C;
- X List();
- X }
- X else {
- X if( (File = fopen( Name = argv[i], "r" )) == NULL )
- X {
- X CANT_OPEN (Name);
- X continue;
- X }
- X if (start_lang == AUTO) {
- X Language = WhichLanguage (Name);
- X }
- X List();
- X if( File != stdin ) fclose(File);
- X }
- X }
- X
- X if( PageNumber > 1 || LineNumber > 0 ) BlankPage();
- X if( StartOdd && ((ActualPageCount % 2) != 0) ) BlankPage();
- X
- X Fini();
- X EndTempFile();
- X
- X if( Printer == POSTSCRIPT ) DumpPostscriptHeader();
- X DumpTableOfContents();
- X DumpTempFiles();
- X Done();
- X}
- X
- XUsage()
- X{
- X char buf[132];
- X char *p;
- X sprintf( buf, "Usage: %s ", ProgName );
- X
- X printf("%s[-CcFhiNnOsS] [-a language] [-H header] [-l pagelen]\n", buf);
- X for(p=buf; *p; *p++ = ' ' );
- X printf("%s[-o offset] [-P printer] [-p[num]] [-r[num]] [-T title]\n", buf);
- X printf("%s[-t tabwidth] [[-f flist] | file...]\n\n", buf );
- X
- X puts("OPTIONS: (first group can be combined)");
- X puts(" -C - Force output of table of contents" );
- X puts(" -c - Print only table of contents (implies -C, overrides -F)" );
- X puts(" -F - Print only file contents" );
- X puts(" -h - Provide help message (you're reading it)" );
- X puts(" -i - Ignore form-feeds in original source");
- X puts(" -N - Number pages of each file starting at page #1" );
- X puts(" -n - Number output lines of each file" );
- X puts(" -O - Force new files to start at an odd numbered actual page" );
- X puts(" -s - Sort TOC by function name within each file" );
- X puts(" -S - Same sort as -s, but ignore case\n" );
- X
- X puts(" -a language - select language class" );
- X puts(" -H header - specify personal heading" );
- X puts(" -l pagelen - define new pagelength" );
- X puts(" -o offset - set offset from left of page" );
- X puts(" -P print - select printer class" );
- X puts(" -p[num] - control function placement on page" );
- X puts(" -r[num] - control function spacing on page" );
- X puts(" -T title - print a title from file 'title'" );
- X puts(" -t tabwidth - set tabwidth" );
- X puts(" -f flist - read 'flist' for list of files to print\n" );
- X
- X puts("Language choices are: C, FORTRAN, ICON, and LISP" );
- X puts("Supported printers: DUMB, BACKSPACE, ANSI, LN03, NECP5200, and POSTSCRIPT");
- X exit(1);
- X}
- X
- Xint SaveOut;
- Xchar *TempName;
- Xchar *Temp2Name;
- X
- XStartTempFile()
- X{
- X int Done();
- X extern char *mktemp();
- X
- X CatchSignalsPlease(Done);
- X
- X SaveOut = dup(1);
- X#if MSDOS | VMS
- X TempName = "cpr0001.tmp";
- X#else
- X TempName = mktemp("/tmp/cprXXXXXX");
- X#endif
- X if( freopen(TempName, "w", stdout) == NULL )
- X {
- X CANT_OPEN (TempName);
- X exit(1);
- X }
- X}
- X
- XEndTempFile()
- X{
- X#if MSDOS | VMS
- X Temp2Name = "cpr0002.tmp";
- X#else
- X Temp2Name = mktemp("/tmp/cprXXXXXX");
- X#endif
- X if( freopen(Temp2Name, "w", stdout) == NULL )
- X {
- X CANT_OPEN (Temp2Name);
- X exit(1);
- X }
- X}
- X
- XDumpTempFiles()
- X{
- X#if (MSDOS | VMS)
- X FILE *f;
- X char b[256];
- X#endif
- X register int pid, w;
- X
- X fclose(stdout);
- X
- X#if !(MSDOS || VMS)
- X dup(SaveOut);
- X while( (pid = fork()) < 0 ) sleep(1);
- X if( pid )
- X while ((w = wait((int *)0)) != pid && w != -1);
- X else
- X {
- X CatchSignalsPlease(SIG_DFL);
- X
- X if( ContentsOnly )
- X execl( "/bin/cat", "cat", Temp2Name, (char *)0 );
- X else {
- X /*
- X Ok, use a heuristic to see if it is worth putting out the
- X table of contents. They seem useless and annoying when cpr
- X is just printing a small job. Heuristic: more than 10 entries
- X in the table of contents AND more than 8 pages of output.
- X */
- X if( !FilesOnly && (AlwaysContents ||
- X (TocCount > SMALLC && TocPages[TocCount-1] > SMALLP)))
- X execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
- X else
- X execl( "/bin/cat", "cat", TempName, (char *)0 );
- X }
- X fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
- X sys_errlist[errno]);
- X exit(1);
- X }
- X#else
- X CatchSignalsPlease(SIG_DFL);
- X /*
- X Use a heuristic to see if it is worth putting out the table of contents.
- X They seem useless and annoying when cpr is printing a small job.
- X Heuristic: > 10 entries in the table of contents or > 8 pages of output.
- X */
- X if( !FilesOnly && (AlwaysContents || (TocCount > SMALLC &&
- X TocPages[TocCount-1] > SMALLP))) {
- X if( (f=fopen(Temp2Name,"r")) == NULL ) {
- X CANT_OPEN (Temp2Name);
- X }
- X else
- X {
- X while( fgets(b, MAXLINE, f) != NULL )
- X write(SaveOut,b,strlen(b));
- X
- X fclose(f);
- X }
- X }
- X if( !ContentsOnly )
- X if( (f=fopen(TempName,"r")) == NULL ) {
- X CANT_OPEN (TempName);
- X }
- X else
- X {
- X while( fgets(b, MAXLINE, f) != NULL )
- X write(SaveOut,b,strlen(b));
- X
- X fclose(f);
- X }
- X#endif
- X}
- X
- XDone()
- X{
- X CatchSignalsPlease(SIG_DFL);
- X
- X fclose( stdout );
- X if( TempName ) unlink( TempName );
- X if( Temp2Name ) unlink( Temp2Name );
- X
- X exit(0);
- X}
- X
- XCatchSignalsPlease(action)
- X#ifdef __TURBOC__
- Xvoid (*action)();
- X#else
- Xint (*action)();
- X#endif
- X{
- X if( signal(SIGINT, SIG_IGN) != SIG_IGN ) signal(SIGINT, action);
- X#ifndef MSDOS
- X if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
- X if( signal(SIGHUP, SIG_IGN) != SIG_IGN ) signal(SIGHUP, action);
- X#endif
- X}
- X
- XList()
- X{
- X register int bp;
- X register char *bufp;
- X char buffer[MAXLINE];
- X
- X NewFile(0);
- X bp = Braces = 0;
- X InString = InComment = 0; /* reset for new file -DV */
- X
- X if (Language == C)
- X SawFunction = 0;
- X else if (Language == FORTRAN)
- X SawFunction = 1; /* Put space after main program END card */
- X else if (Language == NONE)
- X Braces = 1; /* Don't even call LooksLikeFunction */
- X
- X bufp = buffer;
- X while( fgets(bufp, MAXLINE, File) != NULL )
- X {
- X ++FileLineNumber;
- X if( bp ) NewFunction();
- X
- X if( ++LineNumber >= PageEnd ) NewPage();
- X
- X if( bufp[0] == '\f'
- X && bufp[1] == '\n'
- X && bufp[2] == '\0' )
- X {
- X if( !IgnoreFF )
- X NewPage(); /* was strcpy(bufp, "^L\n");*/
- X continue;
- X }
- X
- X if( (Braces == 0) && LooksLikeFunction(bufp) )
- X AddToTableOfContents(NEWFUNCTION);
- X else
- X PutString(buffer, -1, NumberFlag, 1);
- X
- X if (Language != NONE)
- X bp = Scan(buffer);
- X }
- X}
- X
- XScan(l)
- Xregister char *l;
- X{
- X extern char *EndComment();
- X extern char *EndString();
- X register char c;
- X int bp, offset;
- X char *save;
- X
- X bp = 0;
- X switch (Language) {
- X case C:
- X for( save = l; c = *l; ++l )
- X if( InComment )
- X l = EndComment(l);
- X else if( InString )
- X l = EndString(l);
- X else
- X switch(c)
- X {
- X case '{':
- X ++Braces;
- X break;
- X
- X case '}':
- X if( --Braces == 0 )
- X bp = 1;
- X break;
- X
- X case '\'':
- X for( ++l; *l && *l != '\''; ++l )
- X if( *l == '\\' && *(l+1) ) ++l;
- X break;
- X
- X case '"':
- X InString = 1;
- X break;
- X
- X case '/':
- X if( *(l+1) == '*' )
- X {
- X InComment = 1;
- X ++l;
- X }
- X break;
- X }
- X break;
- X case FORTRAN:
- X /* Just check for an END card to indicate the routine is over... */
- X save = l;
- X while (isdigit(*l)) ++l; /* Skip over any line statements. */
- X while (*l && (*l == ' ' || *l == '\t')) ++l; /* Get to non-blank */
- X /* Icon really should only compare against lower case here. */
- X if (save != l && (offset = Compare (l, "END"))) {
- X /*
- X Check to make sure it isn't an ENDIF or some other variable name
- X (Unfortunately, build in a VMS ! comment checker here...)
- X */
- X l += offset;
- X if (*l == '\n' || *l == '!') {
- X Braces = 0;
- X bp = 1;
- X }
- X }
- X break;
- X case ICON:
- X /* Just check for an end keyword to indicate the routine is over... */
- X save = l;
- X while (*l && (*l == ' ' || *l == '\t')) ++l; /* Get to non-blank */
- X if (l[0] == 'e' && l[1] == 'n' && l[2] == 'd') {
- X /*
- X Check to make sure it isn't an ENDIF or some other variable name
- X */
- X l += 3;
- X if (*l == '\n' || *l == '#') {
- X Braces = 0;
- X bp = 1;
- X }
- X }
- X break;
- X case LISP:
- X /*
- X Lisp requires the context to be preserved, hence Braces stays 0 (a
- X lie) and LooksLikeLisp() handles everything.
- X */
- X break;
- X }
- X return(bp);
- X}
- X
- XPutString (str, len, line, newline)
- Xchar *str;
- Xint len;
- Xint line;
- Xint newline;
- X{
- X/*
- X All lines of program text that are written through here are checked for
- X tabs. This should include all parts of each line of code (to keep the
- X internal column counter straight).
- X*/
- X static char *lbuf = (char *)0;
- X static int lbuflen = 0;
- X static char spaces[] = {" "};
- X static int col = 0;
- X static int front=1;
- X int i, need;
- X register char *d, *s, c;
- X
- X if (len == -1) len = strlen (str);
- X
- X need =(len+OffsetValue+20)<<1; /* mult by 2, so that \ work for postcript
- X */
- X if( need > lbuflen ) {
- X if( lbuf ) free(lbuf);
- X lbuflen = need;
- X lbuf = (char *)malloc(lbuflen);
- X if( ! lbuf ) {
- X fprintf( stderr, "MALLOC error, insufficient memory\n" );
- X exit(1);
- X }
- X }
- X *lbuf = '\0';
- X
- X if( OffsetValue && front ) sprintf (lbuf, "%.*s", OffsetValue, spaces);
- X if( line && front ) {
- X sprintf (lbuf, "%6d ", FileLineNumber);
- X }
- X front = 0;
- X col = strlen(lbuf);
- X d = lbuf+col;
- X
- X s = str;
- X for (i=0; i < len; ++i, ++s) {
- X c = *s;
- X switch (c) {
- X case '\t':
- X do {
- X *d++ = ' ';
- X } while (col++ % TabWidth != (TabWidth - 1));
- X break;
- X case '\b':
- X *d++ = c;
- X if (col > 0) --col;
- X break;
- X case '\n':
- X col = 0;
- X if( s[1] ) *d++ = '\n';
- X break;
- X case '\f':
- X col = 0;
- X *d++ = c;
- X break;
- X
- X case '(':
- X case ')':
- X if( Printer == POSTSCRIPT ) {
- X *d++ = '\\';
- X *d++ = c;
- X break;
- X }
- X /*FALLTHROUGH*/
- X
- X default:
- X *d++ = c;
- X ++col;
- X }
- X }
- X *d++ = '\0';
- X
- X switch(Printer) {
- X case POSTSCRIPT:
- X printf( "(%s) %s\n", lbuf, newline ? "s":"sn" );
- X break;
- X
- X default:
- X printf( "%s", lbuf );
- X if(newline) putchar('\n');
- X break;
- X }
- X if( newline ) front = 1;
- X}
- X
- XPutBold (bstr, len, flag)
- Xchar *bstr;
- Xint len, flag;
- X/*-
- X Put ``str'' bolded on stdout (possibly using ^H's). (This test a flag
- X to support other types of bolding options.) Assume ``str'' is ``len''
- X characters long, unless ``len'' == -1, then use strlen for the length
- X of ``str''. If ``flag'' is 0 then print here without calling PutString
- X (in other words, don't pass it on as part of a code line for tab
- X column counting/expansion).
- X
- X When working with escape sequences, don't call PutString to print out the
- X escape sequences themselves. Otherwise the tab expansion will be off.
- X (PutString adjusts column counter for \b's, but it doesn't need to know
- X about escape sequences.)
- X*/
- X{
- X int str_flag = 0;
- X char *str;
- X
- X if( len == -1 ) {
- X len = strlen(bstr);
- X str = bstr;
- X }
- X else {
- X str_flag = 1;
- X str = malloc(len+2);
- X strncpy(str, bstr, len);
- X }
- X
- X switch (Printer) {
- X case DUMB:
- X PutString (str, len, NumberFlag, 0); /* Just give up--printer is too
- X dumb */
- X break;
- X case ANSI:
- X case LN03:
- X printf ("\033[1m");
- X PutString (str, len, NumberFlag, 0);
- X printf ("\033[22m");
- X break;
- X case NECP5200:
- X printf ("\033E");
- X PutString (str, len, NumberFlag, 0);
- X printf ("\033F");
- X break;
- X case POSTSCRIPT:
- X printf( "(%s) sb\n", str );
- X break;
- X
- X case BACKSPACE:
- X {
- X int j, k;
- X char *buf, *s;
- X
- X s = buf = (char *)malloc(len*3+10);
- X for( k=0; *str; ) {
- X *s++ = *str;
- X *s++ = '\b';
- X *s++ = *str++;
- X k += 3;
- X }
- X *s++ = '\0';
- X /*
- X strcpy( s, str );
- X s += len;
- X for(k=0; k<len; k++ ) *s++='\b';
- X strcpy( s, str );
- X */
- X
- X if (flag)
- X PutString (buf, k, NumberFlag, 0);
- X else
- X printf(buf);
- X free(buf);
- X }
- X break;
- X
- X default:
- X fprintf (stderr, "Unknown printer type in PutBold\n");
- X exit (1);
- X }
- X if( str_flag ) free(str);
- X}
- X
- Xchar *
- XEndComment(p)
- Xregister char *p;
- X{
- X register char c;
- X
- X /*
- X * Always return pointer to last non-null char looked at.
- X */
- X while( c = *p++ )
- X if( c == '*' && *p == '/' )
- X {
- X InComment = 0;
- X return(p);
- X }
- X return(p-2);
- X}
- X/* cpr got too big to ship as mail so I'm splitting it here... jdc */
- X#include "cpr.c2"
- END_OF_FILE
- if test 27280 -ne `wc -c <'cpr.c'`; then
- echo shar: \"'cpr.c'\" unpacked with wrong size!
- fi
- # end of 'cpr.c'
- fi
- if test -f 'intro.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'intro.doc'\"
- else
- echo shar: Extracting \"'intro.doc'\" \(9883 characters\)
- sed "s/^X//" >'intro.doc' <<'END_OF_FILE'
- X
- XGPLOTLIB Introduction
- XBy John Campbell 3/90
- X
- XGPLOTLIB is an attempt to create a library of graphics routines out of the
- Xgnuplot package in order to gain access to all the terminal drivers that
- Xhave been written. Note that gnuplot itself does not use these routines,
- Xalthough the routines here have simply been extracted from the original
- Xcode. Unfortunately for maintainers, some of the routines had to be
- Xchanged--generally simplified--in order to create a usable graphics plot
- Xlibrary.
- X
- XNote that an effort was made to avoid name space pollution. This wasn't
- Xnecessary in the original gnuplot code, but a library that is going to
- Xpossibly be embedded in other packages should take some care regarding the
- Xnames used by global symbols. To this end, all globals begin with either
- XGT or GSR and all external routine names begin with either ``gt_'' or
- X``gsr_''. Hence the routine ``test_term()'' from gnuplot/term.c becomes
- X``gt_test_term()'' in gplotlib/gterm.c. Many other internal routines
- Xwere made static to keep them from being external to the module.
- X
- XThe package itself consists of two 'C' modules and two header files:
- Xgsr.h, gsr.c and gterm.c, gterm.h. The latter pair directly use the
- Xfiles in gnuplot/term and should be able to handle new terminal drivers
- Xby changing gterm.c exactly as term.c had to be changed. This is the
- Xlowest level of the library, providing direct access to the terminal
- Xdrivers using the external structure ``GTterm_tbl[]'' and the index
- X``GTterm''.
- X
- XIn order to use this lowest level of GPLOTLIB, you need to know how the
- Xterminal drivers of gnuplot function. Russell Lang's README file from
- Xgnuplot/term is included below with some slight modifications (such as
- Xchanging the names of global variables to more closely match those here
- Xin GPLOTLIB).
- X
- XThe other half of the package, gsr.h and gsr.c, provides the same sort of
- Xgraphics support routines that gnuplot itself needed in the module
- Xgraphics.c. Of course, gnuplot knew ahead of time what order it was
- Xgoing to build it's plots and didn't need generic routines. These gsr
- Xroutines attempt to provide a "high-level" user coordinate based plotting
- Xpackage that allows users to easily do tasks similar to those that gnuplot
- Xdoes during interactive plotting.
- X
- XNote that the documentation for all routines is derived directly out of
- Xthe 'C' code using a utility I wrote years ago called ``docu''. Docu looks
- Xfor 'C' comments of the form /*- ... -*/ and extracts the text and any lines
- Xof code above the text to stdout. Thus, only the items deemed of interest
- Xby the library writer are exported to the outside world. The intent, of
- Xcourse, is that the documentation is accurate--at least the calling sequences
- Xshould be exact, as of the time the documentation was run off, because it
- Xshows the actual routine header. Note also, that I filter the output of
- X``docu'' through another program called ``cpr''. The version of ``cpr''
- X(code printer) that I use is probably different than all but the most
- Xrecently submitted version from Dennis Vadura.
- X
- X
- XDOCUMENTATION FOR GNUPLOT TERMINAL DRIVER WRITERS
- XBy Russell Lang 1/90
- X
- XInformation on each terminal device driver is contained in term.c and
- Xthe term/*.trm files. Each driver is contained in a .trm file and is
- X#include'd into term.c. Each driver has a set of initializers in
- Xgterm.c for GTterm_tbl[], an array of struct termentry.
- X
- XHere is the definition of the struct termentry from gtplot.h:
- X
- Xstruct termentry {
- X char *name;
- X char *description;
- X unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
- X FUNC_PTR init,reset,text,scale,graphics,move,vector,linetype,
- X put_text,text_angle,justify_text,point,arrow;
- X};
- X
- XHere's a brief description of each variable:
- X
- XThe char *name is a pointer to a string containing the name
- Xof the terminal. This name is used by the 'set terminal' and
- X'show terminal' commands.
- XThe name must be unique and must not be confused with an abbreviation
- Xof another name. For example if the name "postscript" exists, it is not
- Xpossible to have another name "postscript2".
- XKeep the name under 15 characters.
- X
- XThe char *description is a pointer to a string containing a
- Xdescription of the terminal, which is displayed in response
- Xto the 'set terminal' command.
- XKeep the description under 60 characters.
- X
- Xxmax is the maximum number of points in the x direction.
- XThe range of points used by gnuplot is 0 to xmax-1.
- X
- Xymax is the maximum number of points in the y direction.
- XThe range of points used by gnuplot is 0 to ymax-1.
- X
- Xv_char is the height of characters, in the same units as xmax and ymax.
- XThe border for labelling at the top and bottom of the plot is
- Xcalculated using v_char.
- Xv_char is used as the vertical line spacing for characters.
- X
- Xh_char is the width of characters, in the same units as xmax and ymax.
- XThe border for labelling at the left and right of the plot is
- Xcalculated using h_char.
- XIf the _justify_text function returns FALSE, h_char is used to justify
- Xtext right or centre. If characters are not fixed width, then the
- X_justify_text function must correctly justify the text.
- X
- Xv_tic is the vertical size of tics along the x axis,
- Xin the same units as ymax.
- X
- Xh_tic is the horizontal size of tics along the y axis,
- Xin the same units as xmax.
- X
- X
- XHere's a brief description of what each term.c function does:
- X
- X_init() Called once, when the device is first selected. This procedure
- Xshould set up things that only need to be set once, like handshaking and
- Xcharacter sets etc...
- X
- X_reset() Called when gnuplot is exited, the output device changed or
- Xthe terminal type changed. This procedure should reset the device,
- Xpossibly flushing a buffer somewhere or generating a form feed.
- X
- X_scale(xs,ys) Called just before _graphics(). This takes the x and y
- Xscaling factors as information. If the terminal would like to do its
- Xown scaling, it returns TRUE. Otherwise, it can ignore the information
- Xand return FALSE: GSR routines can do the scaling for you. null_scale is
- Xprovided to do just this, so most drivers can ignore this function
- Xentirely. The Latex driver is currently the only one providing its own
- Xscaling.
- X
- X_graphics() Called just before a plot is going to be displayed. This
- Xprocedure should set the device into graphics mode. Devices which can't
- Xbe used as terminals (like plotters) will probably be in graphics mode
- Xalways.
- X
- X_text() Called immediately after a plot is displayed. This procedure
- Xshould set the device back into text mode if it is also a terminal, so
- Xthat commands can be seen as they're typed. Again, this will probably
- Xdo nothing if the device can't be used as a terminal.
- X
- X_move(x,y) Called at the start of a line. The cursor should move to the
- X(x,y) position without drawing.
- X
- X_vector(x,y) Called when a line is to be drawn. This should display a line
- Xfrom the last (x,y) position given by _move() or _vector() to this new (x,y)
- Xposition.
- X
- X_linetype(lt) Called to set the line type before text is displayed or
- Xline(s) plotted. This procedure should select a pen color or line
- Xstyle if the device has these capabilities.
- Xlt is an integer from -2 to 0 or greater.
- XAn lt of -2 is used for the border of the plot.
- XAn lt of -1 is used for the X and Y axes.
- Xlt 0 and upwards are used for plots 0 and upwards.
- XIf _linetype() is called with lt greater than the available line types,
- Xit should map it to one of the available line types.
- XMost drivers provide 9 different linetypes (lt is 0 to 8).
- X
- X_put_text(x,y,str) Called to display text at the (x,y) position,
- Xwhile in graphics mode. The text should be vertically (with respect
- Xto the text) justified about (x,y). The text is rotated according
- Xto _text_angle and then horizontally (with respect to the text)
- Xjustified according to _justify_text.
- X
- X_text_angle(ang) Called to rotate the text angle when placing the y label.
- XIf ang = 0 then text is horizontal. If ang = 1 then text is vertically
- Xupwards. Returns TRUE if text can be rotated, FALSE otherwise.
- X
- X_justify_text(mode) Called to justify text left, right or centre.
- XIf mode = LEFT then text placed by _put_text is flushed left against (x,y).
- XIf mode = CENTRE then centre of text is at (x,y).
- XIf mode = RIGHT then text is placed flushed right against (x,y).
- XReturns TRUE if text can be justified
- XReturns FALSE otherwise and then _put_text assumes text is flushed left;
- Xjustification of text is then performed by calculating the text width
- Xusing strlen(text) * h_char.
- X
- X_point(x,y,point) Called to place a point at position (x,y).
- Xpoint is -1 or an integer from 0 upwards.
- X6 point types (numbered 0 to 5) are normally provided.
- XPoint type -1 is a dot.
- XIf point is more than the available point types then it should
- Xbe mapped back to one of the available points.
- XTwo _point() functions called do_point() and line_and_point() are
- Xprovided in term.c and should be suitable for most drivers.
- Xdo_point() draws the points in the current line type.
- XIf your driver uses dotted line types (generally because it is
- Xmonochrome), you should use line_and_point() which changes to
- Xline type 0 before drawing the point. line type 0 should be solid.
- X
- X
- X_arrow(sx,sy,ex,ey) Called to draw an arrrow from (sx,sy) to (ex,ey).
- XAn _arrow() function called do_arrow() is provided in term.c which will
- Xdraw arrows using the _move() and _vector() functions.
- XDrivers should use do_arrow unless it causes problems.
- X
- X
- XThe following should illustrate the order in which calls to these
- Xroutines are made:
- X
- X _init()
- X _scale(xs,ys)
- X _graphics()
- X _linetype(lt)
- X _move(x,y)
- X _vector(x,y)
- X _point(x,y,point)
- X _text_angle(angle)
- X _justify(mode)
- X _put_text(x,y,text)
- X _arrow(sx,sy,ex,ey)
- X _text()
- X _graphics()
- X .
- X .
- X _text()
- X _reset()
- X
- X[And, of course, gt_test_term() in gterm.c is a real live example of
- X calling some of these routines. JDC]
- END_OF_FILE
- if test 9883 -ne `wc -c <'intro.doc'`; then
- echo shar: \"'intro.doc'\" unpacked with wrong size!
- fi
- # end of 'intro.doc'
- fi
- echo shar: End of archive 2 \(of 5\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-